/*******************************************************************************
 * Copyright (c) 2014 Francesco Gabbrielli
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Francesco Gabbrielli - initial API and implementation
 ******************************************************************************/
package it.francescogabbrielli.android.solidalapp;

import it.francescogabbrielli.android.solidalapp.NetworkUtils.Status;
import it.francescogabbrielli.android.solidalapp.SolidalApp.DataKey;
import it.francescogabbrielli.android.solidalapp.actions.EndpointsUpdateDevice;
import it.francescogabbrielli.android.solidalapp.deviceendpoint.model.Device;
import it.francescogabbrielli.android.solidalapp.profileendpoint.model.Profile;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;

/**
 * Application settings
 */
@SuppressWarnings("deprecation")
public class SettingsActivity extends SherlockPreferenceActivity 
				implements StatusListener, DataListener, LocationListener,
					ConnectionCallbacks, OnConnectionFailedListener {
	
	private SolidalApp app;
	
	private LocationClient locationClient;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.preferences);
		app = (SolidalApp) getApplicationContext();
		locationClient = new LocationClient(this, this, this);
		
		final SharedPreferences prefs = getSharedPreferences(SolidalApp.class.getCanonicalName(), MODE_PRIVATE);
		
		Preference pref = findPreference("pref_loc_status");
		pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				locationClient.connect();
				return true;
			}
		});
		
		ListPreference notifications = (ListPreference) findPreference(Constants.PREF_NOTIFY);
		notifications.setValue(prefs.getString(Constants.PREF_NOTIFY, "NONE"));
		notifications.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				prefs.edit().putString(Constants.PREF_NOTIFY, (String) newValue).commit();
				Device device = (Device) app.getData(DataKey.DEVICE);
				if (device!=null)
					Action.start(SettingsActivity.this, EndpointsUpdateDevice.class, device);
//				app.alert("NOTIFY: "+prefs.getString(Constants.PREF_NOTIFY, "ALL"));
				return true;
			}
		});
		
		CheckBoxPreference mode = (CheckBoxPreference) findPreference("pref_loc_modality");
		mode.setChecked(app.getData(DataKey.ADDRESS_LOCATION_MANUAL) == null);
		mode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				if ((Boolean) newValue)
					app.setData(DataKey.ADDRESS_LOCATION_MANUAL, null);
				else
					app.setData(DataKey.ADDRESS_LOCATION_MANUAL, true);
				return true;
			}
		});
		
		CheckBoxPreference phone = (CheckBoxPreference) findPreference(Constants.PREF_SHOW_PHONE);
		phone.setChecked(prefs.getBoolean(Constants.PREF_SHOW_PHONE, true));
		phone.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				prefs.edit().putBoolean(Constants.PREF_SHOW_PHONE, (Boolean) newValue).commit();
//				app.alert("PHONE: "+prefs.getBoolean(Constants.PREF_SHOW_PHONE, true));
				return true;
			}
		});
		
		EditTextPreference report = (EditTextPreference) findPreference("pref_report");
		report.setText("");
		report.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				new Report((String) newValue).send(SettingsActivity.this);
//				((EditTextPreference) preference).setText("");
				return false;
			}
		});
		
		Preference credits = findPreference("pref_credits");
		credits.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
			@Override
			public boolean onPreferenceClick(Preference preference) {
				showDialog(DIALOG_CREDITS);
				return false;
			}
		});
		
//		report.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
//			@Override
//			public boolean onPreferenceClick(Preference preference) {
//				//new LogReport(msg).send();
//				return true;
//			}
//		});
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode==RESULT_OK)
			app.alert(R.string.pref_report_ok);
		else
			app.alert(R.string.pref_report_ko);
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		app.setCurrentActivity(this);
		locationClient.connect();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		app.addStatusListener(this);
		app.addDataListener(this);
				
		app.registerToServices();
		
		updateRegistrationStatus();
		updateLocationStatus(null);
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		app.removeDataListener(this);
		app.removeStatusListener(this);
	}
	
	@Override
	protected void onStop() {
		locationClient.disconnect();
		app.removeCurrentActivity(this);
		super.onStop();
	}
	
	@Override
	protected void onDestroy() {
		locationClient = null;
		super.onDestroy();
	}

	@Override
	public void onLocationChanged(Location location) {
		Log.i(SolidalApp.TAG, "LOCATION: "+location);
		app.getStatus().setLocation(location);
		updateLocationStatus(null);
	}

	@Override
	public void onDataChanged(DataEvent event) {
		Log.i(SolidalApp.TAG, "DATA: "+event);
		switch (event.getKey()) {
		case PROFILE:
		case DEVICE:
			updateRegistrationStatus();
			break;
		default:
		}
	}

	@Override
	public void onStatusUpdate(StatusEvent event) {
		Log.i(SolidalApp.TAG, "STATUS: "+event);
		switch(event.getType()) {
		case NETWORK:
			app.registerToServices();
			updateRegistrationStatus();
			break;
		case LOCATION:
			updateLocationStatus(null);
			break;
		case GCM:
			updateRegistrationStatus();
			break;
		default:
		}
	}

	@Override
	public void onConnected(Bundle connectionHint) {
		locationClient.requestLocationUpdates(new LocationRequest(), this);
	}

	@Override
	public void onDisconnected() {
		locationClient.removeLocationUpdates(this);	
	}

	@Override
	public void onConnectionFailed(ConnectionResult result) {
		updateLocationStatus(result);
	}
	
	private void updateLocationStatus(final ConnectionResult result) {
		Location location = (Location) app.getStatus().getLocation();
		Preference pref = findPreference("pref_loc_status");
		if (location!=null) {
			pref.setSummary(getString(R.string.status_location_available, location.getAccuracy()));
			pref.setOnPreferenceClickListener(null);
		} else if (result!=null && result.getErrorCode()==ConnectionResult.SUCCESS) {
			pref.setSummary(R.string.status_location_connected);
			pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
				@Override
				public boolean onPreferenceClick(Preference preference) {
					startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
					return true;
				}				
			});
		} else if (result!=null && result.getErrorCode()!=ConnectionResult.SUCCESS) {
			pref.setSummary(getString(R.string.status_location_error, result.getErrorCode()));
			pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
				@Override
				public boolean onPreferenceClick(Preference preference) {
					try {
						result.getResolution().send();
					} catch(Exception e) {
						Log.e(SolidalApp.TAG, "Cannot resolve location issue "+result.getErrorCode()+": "+e, e);
					}
					return true;
				}
			});
		} else {
			pref.setSummary(R.string.pref_loc_status_desc);
			pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
				@Override
				public boolean onPreferenceClick(Preference preference) {
					AlertDialog.Builder builder = new AlertDialog.Builder(SettingsActivity.this)
						.setTitle(R.string.warning)
						.setMessage(R.string.check_location)
						.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
								dialog.dismiss();
							}
						})
						.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
							}
						});
					builder.show();
					return true;
				}
			});
		}
	}
	
	private void updateRegistrationStatus() {
		Device device = (Device) app.getData(DataKey.DEVICE);
		Profile profile = (Profile) app.getData(DataKey.PROFILE);
		String regId = app.getStatus().getGcmId();
		Preference pref = findPreference("pref_reg_status");
		if (app.getStatus().getNetworkStatus()==Status.CONNECTED) {
			pref.setSummary(R.string.pref_reg_status_desc);
			if (device!=null)
				pref.setSummary(R.string.status_endpoints_registered);
			else if (regId!=null)
				pref.setSummary(R.string.status_endpoints_registering);
			else if (profile!=null)
				pref.setSummary(R.string.status_gcm_registering);
		} else
			pref.setSummary(R.string.status_network_disconnected);
	}

	private final static int DIALOG_CREDITS = 13233;
	
	@Override
	protected Dialog onCreateDialog(int id, Bundle args) {
		
		LayoutInflater inflater = getLayoutInflater();
		
		switch(id) {
		case DIALOG_CREDITS:
			String version = "?";
			try {
				version = app.getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
			} catch(Exception e) {
				Log.e(SolidalApp.TAG, "Unknown version?", e);
			}
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			View view = inflater.inflate(R.layout.dialog_credits, null);
			View.OnClickListener listener = new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					TextView tv = (TextView) v;
					try {
						String url = tv.getText().toString();
						if (!url.startsWith("http"))
							url = tv.getHint().toString();
						Intent i = new Intent(Intent.ACTION_VIEW);
						i.setData(Uri.parse(url));
						startActivity(i);
					} catch(Exception e) {
						Log.e(SolidalApp.TAG, "Error loading credits page: "+tv.getText(), e);
					}
				}
			};
			view.findViewById(R.id.credits_concept)
				.setOnClickListener(listener);
//			view.findViewById(R.id.credits_screenplay)
//				.setOnClickListener(listener);
			view.findViewById(R.id.credits_implementation)
				.setOnClickListener(listener);
			view.findViewById(R.id.credits_applink)
				.setOnClickListener(listener);
			view.findViewById(R.id.credits_abslink)
				.setOnClickListener(listener);
			builder
				.setTitle("Personal Service v"+version)
				.setView(view)
				.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
			return builder.create();
		}
		
		return null;
		
	}
	
}
